package xyj.sparrow.scheduler.cron;

import lombok.*;
import lombok.extern.slf4j.Slf4j;
import xyj.sparrow.scheduler.cron.thread.MonitorThread;
import xyj.sparrow.scheduler.entity.Task;
import xyj.sparrow.scheduler.server.ClientManager;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * cron封装：cron表达式，task任务
 *
 * @author 江南小俊
 * @since 2021/06/14
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Slf4j
public class Cron implements Runnable {
    private MonitorThread monitorThread;
    private CronExpression cronExpression;
    private Task task;
    private LocalDateTime now;

    public Cron(MonitorThread monitorThread, Task task) {
        this.monitorThread = monitorThread;
        this.task = task;
        this.cronExpression = new CronExpression(task.getTaskRules(), task.getTaskId());
    }

    public Cron(String taskId) {
        Task task = new Task();
        task.setTaskId(taskId);
        this.task = task;
    }

    /**
     * 刷新下一次执行时间
     *
     * @return xyj.scheduler.cron.Cron
     * @author 努力努力再努力v
     * @since 2021/6/14
     */

    public Cron refreshTime() {
        cronExpression = cronExpression.getTimeAfter();
        return this;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Cron cron = (Cron) o;
        return Objects.equals(task.getTaskId(), cron.task.getTaskId());
    }

    @Override
    public int hashCode() {
        return Objects.hash(task.getTaskId());
    }

    /**
     * 发起调度
     */
    @Override
    public void run() {
        remoteCall();
        //刷新下次任务执行时间
        monitorThread.addCron(refreshTime());
    }

    /**
     * 远程调用实现
     */
    public void remoteCall() {
        log.info("remoteCall:{}", task);
        ClientManager.scheduling(task.getAppId(), task.getTaskId(),now);
    }
}
